#ifndef CONNECT_H
#define CONNECT_H

#include "header.h"
#include "utils/TcpSocket.h"
#include "utils/byte_buf.h"
#include "parser.h"

using namespace sh;

const string INFO_DATA = "0c 01 00 00 16 00 00 00 63 61 6c 6c 65 72 69 64 "
                         "3d 2f 67 6f 72 6f 73 6c 69 62 5f 73 75 62 12 00 "
                         "00 00 74 6f 70 69 63 3d 2f 72 6f 73 5f 6d 65 73 "
                         "73 61 67 65 1d 00 00 00 74 79 70 65 3d 6d 79 5f "
                         "70 61 63 6b 61 67 65 2f 4d 65 73 73 61 67 65 44 "
                         "65 66 69 6e 65 27 00 00 00 6d 64 35 73 75 6d 3d "
                         "36 63 38 33 62 36 66 39 37 30 65 37 63 63 64 36 "
                         "31 31 33 39 64 39 38 33 61 34 37 39 30 32 36 31 "
                         "7b 00 00 00 6d 65 73 73 61 67 65 5f 64 65 66 69 "
                         "6e 69 74 69 6f 6e 3d 69 6e 74 38 20 73 68 75 74 "
                         "64 6f 77 6e 5f 74 69 6d 65 0a 69 6e 74 33 32 20 "
                         "73 68 75 74 64 6f 77 6e 5f 74 69 6d 65 32 0a 73 "
                         "74 72 69 6e 67 20 74 65 78 74 0a 66 6c 6f 61 74 "
                         "33 32 20 6e 75 6d 0a 73 74 72 69 6e 67 20 74 65 "
                         "78 74 32 0a 69 6e 74 38 5b 5d 20 64 61 74 61 0a "
                         "69 6e 74 31 36 5b 5d 20 64 61 74 61 32 0a 0a 0d "
                         "00 00 00 74 63 70 5f 6e 6f 64 65 6c 61 79 3d 31 ";

string parserPackage(const string &data)
{
    if (data.size() < 4)
    {
        return {};
    }
    ByteBuf byteBuf(data);
    int32_t length = byteBuf.getIntLE(0) + 4;
    if (data.length() < length)
    {
        return {};
    }
    ByteBuf bytes = byteBuf.readBytes(length);
    return string(bytes.data(), bytes.readableBytes());
}

void parserData(const string &data)
{
    static bool first = true;
    ByteBuf byteBuf(data);
    cout << byteBuf.toHexString() << endl;
    if (first)
    {
        first = false;
        return;
    }
    parser(byteBuf);
}

void writeInfoData(TcpSocket *tcpSocket)
{
    string all_data;
    string info_data = StringUtil::replace(INFO_DATA, " ", "");
    ByteBuf byteBuf = ByteBuf::fromHex(info_data);
    if (tcpSocket->writeData(byteBuf.data(), byteBuf.readableBytes()) != byteBuf.readableBytes())
    {
        cout << "write fail" << endl;
        return;
    }

    long int count = 0;
    while (true)
    {
        string data = tcpSocket->readData(1024);
        all_data.append(data);

        string package = parserPackage(all_data);
        all_data = all_data.substr(package.length());
        parserData(package);
        count++;
//        if (count > 3)
//        {
//            break;
//        }
    }
}

void connect2Server(const string &ip, int port)
{
    TcpSocket tcpSocket;
    tcpSocket.connectToHost(ip, port);
    if (!tcpSocket.waitForConnected(2000))
    {
        cout << "connect to server fail" << endl;
        return;
    }
    writeInfoData(&tcpSocket);
}

#endif //CONNECT_H
